package com.edward.puff.config;

import com.edward.puff.repository.TransLogRepository;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * @Author: Edward
 * @Date: 2019/11/28 下午4:59
 */
public class PuffConfiguration implements ApplicationContextAware {

    /**
     * 全局上下文
     */
    private ApplicationContext context;

    /**
     * signature <==> puff元数据
     */
    @Setter
    private Map<String, PuffMetadata> metadataCache;

    /**
     * method.toString <==> signature , 避免每次调用都需要MD5计算签名
     */
    @Setter
    private Map<String, String> signatureCache;

    /**
     * 全局Repository实现类class
     */
    @Setter
    private Class<? extends TransLogRepository> globalRepoClass;

    /**
     * 全局线程池
     */
    @Getter
    private Executor globalExecutor = Executors.newFixedThreadPool(100);

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }

    /**
     * 根据方法,获取签名
     */
    public PuffMetadata getPuffMetadata(String methodStr) {
        String signature = signatureCache.get(methodStr);
        if (StringUtils.isEmpty(signature)) {
            throw new RuntimeException(methodStr + "is not puff aop method");
        }
        return getPuffMetadataBySign(signature);
    }

    public PuffMetadata getPuffMetadataBySign(String signature) {
        PuffMetadata metadata = metadataCache.get(signature);
        if (metadata == null) {
            throw new RuntimeException(signature + "is not puff aop method");
        }
        return metadata;
    }

    /**
     * 根据类型,获取Bean对象
     */
    public <T> T getBean(Class<T> clazz) {
        return context.getBean(clazz);
    }

    /**
     * 根据beanName,获取Bean对象
     */
    public Object getBean(String beanName) {
        return context.getBean(beanName);
    }

    /**
     * 获取全局repository
     */
    public TransLogRepository getGlobalRepository() {
        return getBean(globalRepoClass);
    }
}
